package com.turing.post.capitalaccounts.impl;

import java.math.BigInteger;
import java.util.Date;

import javax.ejb.EJB;
import javax.ejb.Local;
import javax.ejb.Remote;
import javax.ejb.Stateless;

import com.turing.post.capitalaccounts.util.BankAccountDetail;
import com.turing.post.capitalaccounts.util.BankAccountDetailDao;
import com.turing.post.capitalaccounts.util.CapitalApplicationException;
import com.turing.post.capitalaccounts.util.CapitalRespCode;
import com.turing.post.capitalaccounts.util.SaleCapitalDetail;
import com.turing.post.capitalaccounts.util.SaleCapitalDetailDao;
import com.turing.post.capitalaccounts.util.SaleCashWithdrawBill;
import com.turing.post.capitalaccounts.util.SaleCashWithdrawBillBusiness;
import com.turing.post.capitalaccounts.util.SaleCashWithdrawBillDao;
import com.turing.post.common.util.PCPSCommonDao;
import com.turing.post.common.util.SysOpUser;
import com.turing.post.common.util.SysOpUserDao;
import com.turing.post.common.util.SysOperLog;
import com.turing.post.common.util.SysOperLogDao;
import com.turing.post.organization.util.IssueCompany;
import com.turing.post.organization.util.IssueCompanyDao;
import com.turing.post.organization.util.SaleBranch;
import com.turing.post.organization.util.SaleBranchDao;
import com.turing.post.util.PCPSApplicationException;
import com.turing.post.util.PCPSUtil;
import com.turing.post.util.PCPSWebInput;

/**
 * @author zxp
 * @Jan 6, 2013
 */
@Stateless(mappedName = "capitalaccounts.impl.SaleCashWithdrawBillBusinessImpl")
@Remote
@Local
public class SaleCashWithdrawBillBusinessImpl implements
		SaleCashWithdrawBillBusiness {

	@EJB(mappedName = "common.impl.SysOperLogDaoImpl")
	private SysOperLogDao sysOperLogDaoImpl;

	@EJB(mappedName = "capitalaccounts.impl.SaleCashWithdrawBillDaoImpl")
	private SaleCashWithdrawBillDao saleCashWithdrawBillDaoImpl;

	@EJB(mappedName = "organization.impl.IssueCompanyDaoImpl")
	private IssueCompanyDao issueCompanyDaoImpl;

	@EJB(mappedName = "common.impl.PCPSCommonDaoImpl")
	private PCPSCommonDao pcpsCommonDaoImpl;

	@EJB(mappedName = "common.impl.SysOpUserDaoImpl")
	private SysOpUserDao sysOpUserDaoImpl;

	@EJB(mappedName = "organization.impl.SaleBranchDaoImpl")
	private SaleBranchDao saleBranchDaoImpl;

	@EJB(mappedName = "capitalaccounts.impl.SaleCapitalDetailDaoImpl")
	private SaleCapitalDetailDao saleCapitalDetailDaoImpl;

	@EJB(mappedName = "capitalaccounts.impl.BankAccountDetailDaoImpl")
	private BankAccountDetailDao bankAccountDetailDaoImpl;

	/**
	 * 检查当前操作机构是否处于日终状态
	 * 
	 * @param branchNo
	 * @throws PCPSApplicationException
	 */
	private SaleBranch checkSaleBranchDayOff(String branchNo)
			throws PCPSApplicationException {
		if (PCPSUtil.isEmpty(branchNo)) {
			throw new CapitalApplicationException(
					CapitalApplicationException.ERRMSG_NULLPOINTER,
					CapitalRespCode.OPER_NULL, "无效的销售机构号码!");
		}
		SaleBranch sb = saleBranchDaoImpl.getSaleBranchBySaleBranchNo(branchNo);
		if (sb == null) {
			throw new CapitalApplicationException(
					CapitalApplicationException.ERRMSG_NULLPOINTER,
					CapitalRespCode.OPER_NULL, "销售机构机构信息未获取到!");
		}
		if (SaleBranch.In_DayOff.equals(sb.getDayOff())) {
			throw new CapitalApplicationException(
					CapitalApplicationException.ERRMSG_NULLPOINTER,
					CapitalRespCode.OPER_NULL, "销售机构已日结，禁止办理业务!");
		}
		return sb;
	}

	@Override
	public void insertSaleCashWithdrawBill(PCPSWebInput webInput,
			SaleCashWithdrawBill obj, BankAccountDetail bankAcc)
			throws PCPSApplicationException {
		// 业务检查
		if (obj == null || webInput == null || bankAcc == null) {
			throw new CapitalApplicationException(
					CapitalApplicationException.ERRMSG_NULLPOINTER,
					CapitalRespCode.RC_ARGS_NULL, "参数为NULL");
		}

		SysOpUser sysOpUser = sysOpUserDaoImpl.getSysOpUserByOperId(webInput
				.getOperId());
		// 判断操作员是否存在
		if (sysOpUser == null) {
			throw new CapitalApplicationException(
					CapitalApplicationException.ERRMSG_NULLPOINTER,
					CapitalRespCode.OPER_NULL, "操作员为NULL");
		}

		SaleBranch saleBranch = checkSaleBranchDayOff(webInput
				.getOperBranchNo());
		// 判断销售机构是否存在
		if (saleBranch == null) {
			throw new CapitalApplicationException(
					CapitalApplicationException.ERRMSG_NULLPOINTER,
					CapitalRespCode.SALEBRANCH_NULL, "销售机构为空!");
		}
		// 上存金额不能小于等于0
		if (obj.getAmount().compareTo(BigInteger.valueOf(0)) <= 0) {
			throw new CapitalApplicationException(CapitalRespCode.AMOUNT_SMALL,
					"缴款金额<=0");
		}
		// 上存金额不能大于当期现金余额
		if (saleBranch.getCash().compareTo(obj.getAmount()) < 0) {
			throw new CapitalApplicationException(CapitalRespCode.AMOUNT_SMALL,
					"上存金额大于当期现金余额!");
		}
		saleBranch.setCash(saleBranch.getCash().subtract(obj.getAmount()));
		saleBranchDaoImpl.updateSaleBranch(saleBranch);
		// 发卡商
		IssueCompany issueCompany = issueCompanyDaoImpl
				.getIssueCompanyByIssueCompanyNo(PCPSUtil
						.getICNoByBranchNo(saleBranch.getSaleBranchNo()));

		// 判断机构缴款明细凭证号码是否已经被用过
		if (saleCashWithdrawBillDaoImpl.checkSaleCashWithdrawBillVoucherNo(
				issueCompany.getIssueCompanyNo(), obj.getVoucherNo()) > 0) {
			throw new CapitalApplicationException(CapitalRespCode.AMOUNT_SMALL,
					"凭证号" + obj.getVoucherNo() + "已经存在!");
		}
		// 判断银行转账帐户入账流水凭证号码是否已经被用过
		if (bankAccountDetailDaoImpl.checkBankAccountDetailVoucherNo(
				issueCompany.getIssueCompanyNo(), obj.getVoucherNo()) > 0) {
			throw new CapitalApplicationException(CapitalRespCode.AMOUNT_SMALL,
					"凭证号" + obj.getVoucherNo() + "已经存在!");
		}

		// 取当前时间
		Date curTime = pcpsCommonDaoImpl.getDatabaseSysTime();
		// 机构上存款录入
		BigInteger saleCashWithdrawBillId = pcpsCommonDaoImpl
				.getUniqueIntegerKey();
		obj.setSaleCashWithdrawBillId(saleCashWithdrawBillId);
		obj.setSaleBranchNo(saleBranch.getSaleBranchNo());
		obj.setTranDate(issueCompany.getTranDate());
		obj.setTranTime(curTime);
		obj.setOperId(webInput.getOperId());
		saleCashWithdrawBillDaoImpl.insertSaleCashWithdrawBill(obj);
		// 插入销售机构资金明细
		SaleCapitalDetail saleCapitalDetail = new SaleCapitalDetail();
		saleCapitalDetail.setSaleBranchNo(obj.getSaleBranchNo());
		saleCapitalDetail.setTranDate(issueCompany.getTranDate());
		saleCapitalDetail.setTranTime(curTime);
		saleCapitalDetail.setTranType(SaleCapitalDetail.TRANTYPE_DEPOSITCASH);
		saleCapitalDetail.setTicketId(saleCashWithdrawBillId);
		// saleCapitalDetail.setCashDeposit(obj.getAmount());
		saleCapitalDetail.setCashWithdraw(obj.getAmount());
		saleCapitalDetail.setOperId(obj.getOperId());
		saleCapitalDetail.setRemark(obj.getRemark());

		// 银行账户
		BigInteger bankAccountId = obj.getPayeeBankAccountId();
		saleCapitalDetailDaoImpl.insertSaleCapitalDetail(saleCapitalDetail);

		// 日志记录
		sysOperLogDaoImpl.insertSysOperLogInfo(webInput,
				SysOperLog.operType_Add, "新增销售机构上存/缴现金支出单",
				"SaleCashWithdrawBillId:" + obj.getSaleCashWithdrawBillId()
						+ "SaleBranchNo:" + obj.getSaleBranchNo());

		// 银行转账帐户入账流水表
		BankAccountDetail bad = new BankAccountDetail();
		bad.setBankAccDetailId(saleCashWithdrawBillId);// pcpsCommonDaoImpl.getUniqueIntegerKey();
		// 银行帐户ID
		bad.setBankAccountId(bankAccountId);
		// 银行记账流水号
		// bad.setBankAccSeqNo(bankAcc.getBankAccSeqNo());
		bad.setCreateBranchNo(webInput.getOperBranchNo());// 录入人机构号
		bad.setVoucherNo(bankAcc.getVoucherNo());
		bad.setVoucherAmount(bankAcc.getVoucherAmount());
		bad.setVoucherRemark(bankAcc.getVoucherRemark());
		bad.setVoucherImageId(bankAcc.getVoucherImageId());
		bad.setOperId(webInput.getOperId());
		bad.setCreateTime(pcpsCommonDaoImpl.getDatabaseSysTime());
		bad.setDebitAmount(BigInteger.ZERO);// 累计借方发生额
		// 添加时状态为未核对
		bad.setStauts(BankAccountDetail.STATUS_NOCHECK);// 现金上缴
		bad.setPaidType(BankAccountDetail.Cash_PaidType);
		bad.setRemark("销售机构现金上缴");
		bankAccountDetailDaoImpl.addBankAccountDetail(bad);
		// 记录操作日志
		sysOperLogDaoImpl
				.insertSysOperLogInfo(webInput, SysOperLog.operType_Add,
						"添加银行账户入账流水明细", "银行帐号：" + bad.getBankAccountId()
								+ "；凭证号：" + bad.getVoucherNo());
	}

	@Override
	public void cancelSaleCashWithdrawBill(PCPSWebInput webInput,
			SaleCashWithdrawBill obj) throws PCPSApplicationException {
		// 业务检查
		if (obj == null || webInput == null) {
			throw new CapitalApplicationException(
					CapitalApplicationException.ERRMSG_NULLPOINTER,
					CapitalRespCode.RC_ARGS_NULL, "参数为NULL");
		}

		SysOpUser sysOpUser = sysOpUserDaoImpl.getSysOpUserByOperId(webInput
				.getOperId());
		// 判断操作员是否存在
		if (sysOpUser == null) {
			throw new CapitalApplicationException(
					CapitalApplicationException.ERRMSG_NULLPOINTER,
					CapitalRespCode.OPER_NULL, "操作员为NULL");
		}
		SaleBranch saleBranch = checkSaleBranchDayOff(webInput
				.getOperBranchNo());
		// 根据现金上存/缴单ID得到详细信息
		SaleCashWithdrawBill oldObj = saleCashWithdrawBillDaoImpl
				.getSaleCashWithdrawBillById(obj.getSaleCashWithdrawBillId());
		// 判断此账单是否已被撤销
		if (null == oldObj) {
			throw new CapitalApplicationException(
					CapitalApplicationException.ERRCODE_CATEGORY_APPLICATION,
					CapitalRespCode.SaleCreditDepositBill_null, "不存在此账单!");
		}
		// 判断此账单是否已被撤销
		if (null != oldObj.getCancelSaleCashWithdrawBillId()) {
			throw new CapitalApplicationException(
					CapitalApplicationException.ERRCODE_CATEGORY_APPLICATION,
					CapitalRespCode.BILL_IS_CANCEL, "此账单已被撤销!");
		}
		// 判断此账单是否为当前操作员所录入的账单
		if (!oldObj.getOperId().equals(sysOpUser.getOperId())) {
			throw new CapitalApplicationException(
					CapitalApplicationException.ERRCODE_CATEGORY_APPLICATION,
					CapitalRespCode.SaleCreditDepositBill_not_same_oper,
					"被撤单据应为同一操作员!");
		}
		// 修改原始记录取消单号,交叉记录
		BankAccountDetail bad = bankAccountDetailDaoImpl
				.getBankAccountDetailByID(obj.getSaleCashWithdrawBillId());
		if (bad != null) {
			if (!bad.getStauts().equals(BankAccountDetail.STATUS_NOCHECK)) {
				throw new CapitalApplicationException(
						CapitalApplicationException.ERRMSG_NULLPOINTER,
						CapitalRespCode.RC_ARGS_NULL, "已核对现金上缴单不可撤销!");
			}
			// BankAccountDetail badInsert = new BankAccountDetail();
			// badInsert.setBankAccDetailId(pcpsCommonDaoImpl
			// .getUniqueIntegerKey());
			// // 银行帐户ID
			// badInsert.setBankAccountId(bad.getBankAccountId());
			// // 银行记账流水号
			// badInsert.setBankAccSeqNo(bad.getBankAccSeqNo());
			// badInsert.setCreateBranchNo(webInput.getOperBranchNo());// 录入人机构号
			// badInsert.setVoucherNo(bad.getVoucherNo());
			// badInsert.setVoucherAmount(bad.getVoucherAmount());
			// badInsert.setVoucherRemark(bad.getVoucherRemark());
			// badInsert.setVoucherImageId(bad.getVoucherImageId());
			// badInsert.setOperId(webInput.getOperId());
			// badInsert.setCreateTime(pcpsCommonDaoImpl.getDatabaseSysTime());
			// badInsert.setDebitAmount(BigInteger.ZERO.subtract(bad
			// .getDebitAmount()));// 累计借方发生额
			// // 添加时状态为未核对
			// badInsert.setStauts(BankAccountDetail.Status_Cancel);
			// badInsert.setRemark("销售机构现金上缴撤销");
			// bankAccountDetailDaoImpl.addBankAccountDetail(badInsert);
			bad.setStauts(BankAccountDetail.Status_Cancel);
			bankAccountDetailDaoImpl.modifyBankAccountDetail(bad);
		}

		saleBranch.setCash(saleBranch.getCash().add(oldObj.getAmount()));
//		IssueCompany ic = issueCompanyDaoImpl
//				.getIssueCompanyByIssueCompanyNo(PCPSUtil
//						.getICNoByBranchNo(saleBranch.getSaleBranchNo()));
		// 判断撤销后是否超过现金库
//		if (ic.getCashUpperLimit().compareTo(BigInteger.ZERO) > 0
//				&& saleBranch.getCash().compareTo(ic.getCashUpperLimit()) > 0) {
//			throw new CapitalApplicationException(
//					CapitalApplicationException.ERRMSG_NULLPOINTER,
//					CapitalRespCode.SALEBRANCH_NULL, "撤销后销售机构现金库"
//							+ get100(saleBranch.getCash()) + "大于发卡商现金库上限"
//							+ get100(ic.getCashUpperLimit()));
//		}
		saleBranchDaoImpl.updateSaleBranch(saleBranch);
		// 发卡商
		IssueCompany issueCompany = issueCompanyDaoImpl
				.getIssueCompanyByIssueCompanyNo(PCPSUtil
						.getICNoByBranchNo(saleBranch.getSaleBranchNo()));
		// 取当前时间
		Date curTime = pcpsCommonDaoImpl.getDatabaseSysTime();
		// 机构上存款撤销
		BigInteger saleCashWithdrawBillId = pcpsCommonDaoImpl
				.getUniqueIntegerKey();
		obj.setSaleCashWithdrawBillId(saleCashWithdrawBillId);
		obj.setSaleBranchNo(saleBranch.getSaleBranchNo());
		obj.setTranDate(issueCompany.getTranDate());
		obj.setTranTime(curTime);
		obj.setAmount(BigInteger.valueOf(0).subtract(oldObj.getAmount()));
		obj.setPayeeBankAccountId(oldObj.getPayeeBankAccountId());
		obj.setCancelSaleCashWithdrawBillId(oldObj.getSaleCashWithdrawBillId());
		obj.setOperId(webInput.getOperId());
		saleCashWithdrawBillDaoImpl.insertSaleCashWithdrawBill(obj);

		oldObj.setCancelSaleCashWithdrawBillId(saleCashWithdrawBillId);
		saleCashWithdrawBillDaoImpl.updateSaleCashWithdrawBill(oldObj);
		// 插入销售机构资金明细
		SaleCapitalDetail saleCapitalDetail = new SaleCapitalDetail();
		saleCapitalDetail.setSaleBranchNo(obj.getSaleBranchNo());
		saleCapitalDetail.setTranDate(issueCompany.getTranDate());
		saleCapitalDetail.setTranTime(curTime);
		saleCapitalDetail
				.setTranType(SaleCapitalDetail.TRANTYPE_CANCELDEPOSITCASH);
		saleCapitalDetail.setTicketId(saleCashWithdrawBillId);
		// saleCapitalDetail.setCashDeposit(BigInteger.ZERO.subtract(oldObj.getAmount()));
		saleCapitalDetail.setCashWithdraw(BigInteger.ZERO.subtract(oldObj
				.getAmount()));
		saleCapitalDetail.setOperId(obj.getOperId());
		saleCapitalDetail.setRemark(obj.getRemark());
		saleCapitalDetailDaoImpl.insertSaleCapitalDetail(saleCapitalDetail);
	}

//	private String get100(BigInteger a) {
//		DecimalFormat numf = new DecimalFormat();
//		double d = Double.parseDouble(a.toString()) / 100;
//		numf.applyPattern("#,###,###,##0.00");
//		if (d == 0)
//			return "0.00";
//		else
//			return numf.format(d);
//	}
}